# -*- coding: utf-8 -*-
# @Time    : 2024/6/7 9:56
# @Author  : wangwei
# @File    : conftest.py
import os
import threading
import time
from typing import List

import allure
import pytest
from PIL import Image

from common.AppKeyword import Appkeyword
from excel_ddt import ddt
from get_path import get_pathdir


def pytest_collection_modifyitems(
        session: "Session", config: "Config", items: List["Item"]
) -> None:
    # item表示每个测试用例，解决用例名称中文显示问题
    for item in items:
        item.name = item.name.encode("utf-8").decode("unicode-escape")
        item._nodeid = item._nodeid.encode("utf-8").decode("unicode-escape")

@pytest.fixture(scope='session', autouse=True)
def aaget_driver():
    ddt.appkeyword.sleep("1")
    ddt.appkeyword.logger.info("最开始执行语句")
# 日志初始化

@pytest.fixture(scope='function', autouse=True)
def case_teardown(worker_id):
    time.sleep(1)
    yield
    # 用例结束后，停止循环截图
    global shot_flag
    shot_flag = False
    # 拼接临时图片，形成当前用例的gif动态图
    # 从临时目录中读取当前进程下所有png图片，存入img_list中
    img_list = []  # 存储很多个图片
    for img in os.listdir(f'{get_pathdir}/video'):
        if img.startswith(worker_id) and img.endswith('.png'):
            img_list.append(img)
    # 从目录得到的所有图片的名称排序是不对的，拼接gif需要顺序来
    # 所以我们针对img_list进行排序
    print(img_list)
    img_list.sort(key=lambda name: int(name.split('_')[1][:-4]))
    # 获取第一个图片对应的二进制对象
    if img_list:
        print(img_list)
        first_img = Image.open(f'{get_pathdir}/video/{img_list[0]}')
        eles_img = []  # 用来存储剩下的图片的二进制对象
        for img in img_list[1:]:
            cur_img = Image.open(f'{get_pathdir}/video/{img}')
            eles_img.append(cur_img)
        # 拼接
        first_img.save(f'{get_pathdir}/video/{worker_id}record.gif',
                       append_images=eles_img,
                       duration=300,  # 每隔多长时间播放一张图片
                       save_all=True,
                       loop=2  # 表示循环次数
                       )
        # 将生成的gif动态图放入allure测试报告之中
        with open(f'{get_pathdir}/video/{worker_id}record.gif', mode='rb') as f:
            allure.attach(f.read(), '执行回放', attachment_type=allure.attachment_type.GIF)
        # 每个用例结束后，gif生成后，都去清除当前进程下的临时图片及gif动态图
        for img in os.listdir(f'{get_pathdir}/video'):
            if img.startswith(worker_id):
                os.remove(f'{get_pathdir}/video/{img}')
    # 关闭窗口只剩下一个




# def pytest_addoption(parser):
#     parser.addoption('--browsers', action='store')


# @pytest.fixture(scope='session', autouse=True)
# def get_browser(request, worker_id):
#     # 得到--browsers对应的chrome,firefox
#     browsers = request.config.getoption('--browsers')
#     if browsers:
#         # 将得到的browsers，转成列表
#         browsers_list = browsers.split(',')
#         if worker_id == 'master':
#             return browsers_list[0]
#         else:
#             # gw0、gw1、gw2...gw100
#             index = int(worker_id[2:])
#             return browsers_list[index]
#     else:
#         return 'chrome'


# @pytest.hookimpl(tryfirst=True, hookwrapper=True)
# def pytest_runtest_makereport():
#     outcome = yield
#     res = outcome.get_result()  # 获取当前用例执行的结果
#     # 如果用例还在被调用并且失败了，那么我就去截图
#     if res.when == 'call' and res.failed:
#         # 做截图
#         # 这里的截图不要存在本地，因为我们要将其放在测试报告上面
#         img = ddt.appkeyword.driver.get_screenshot_as_png()
#         # 加到allure测试报告上
#         allure.attach(img, '失败截图', attachment_type=allure.attachment_type.PNG)


def shot(dr, worker_id):  # dr就是driver，worker_id是进程id
    # 每次截图前开始前，都去清除当前进程下的临时图片及gif动态图
    for img in os.listdir(f'{get_pathdir}/video'):
        if img.startswith(worker_id):
            os.remove(f'{get_pathdir}/video/{img}')
    global shot_flag  # 全局变量，用来控制每条用例截图的开始和结束
    shot_flag = True
    i = 0  # 用例给图片命名的，用他来排序
    while shot_flag:
        # 只要shot_flag为True，那么这个循环就一直在截图
        # 调用driver的截图方法，生成临时图片文件
        try:
            if ddt.appkeyword and ddt.appkeyword.driver:
                print("截图开始了")
                dr.get_screenshot_as_file(f'{get_pathdir}/video/{worker_id}_{i}.png')
                print("完成截图")
                time.sleep(0.3)
                i += 1
        except:
            return  # 如果截图中有异常就结束这个循环


@pytest.fixture(scope="function", autouse=True)
def start_thread(worker_id):
    if ddt.appkeyword:
        th = threading.Thread(target=shot, args=(ddt.appkeyword, worker_id))
        th.start()
